package cn.chengpengper.shortlink.service.impl;

import cn.chengpengper.shortlink.component.SmsComponent;
import cn.chengpengper.shortlink.config.SmsConfig;
import cn.chengpengper.shortlink.constant.RedisKeyTemplate;
import cn.chengpengper.shortlink.constant.ShortLinkConstant;
import cn.chengpengper.shortlink.controller.request.SendCodeRequest;
import cn.chengpengper.shortlink.enums.BizCodeEnum;
import cn.chengpengper.shortlink.enums.SendCodeEnum;
import cn.chengpengper.shortlink.service.NotifyService;
import cn.chengpengper.shortlink.util.CheckUtil;
import cn.chengpengper.shortlink.util.CommonUtil;
import cn.chengpengper.shortlink.util.JsonData;
import cn.chengpengper.shortlink.util.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @author huchengpeng
 * @version v1.0.0
 * @date 2023/8/20 18:44
 * @description 通知服务
 */
@Slf4j
@Service
public class NotifyServiceImpl implements NotifyService {

    private static final Long CODE_EXPIRED_TIME = 60 * 1000L;

    @Autowired
    private SmsComponent smsComponent;

    @Autowired
    private SmsConfig smsConfig;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public JsonData sendCode(String keyTemplate, HttpServletRequest request, SendCodeRequest sendCodeRequest) {
        String key = RedisKeyUtil.getCaptchaKey(keyTemplate, request);

        String cacheCaptcha = redisTemplate.opsForValue().get(key);

        String captcha = sendCodeRequest.getCaptcha();

        if (StringUtils.isBlank(captcha)
                || StringUtils.isBlank(cacheCaptcha)
                || !StringUtils.equalsIgnoreCase(cacheCaptcha, captcha)) {
            return JsonData.buildResult(BizCodeEnum.CODE_CAPTICHA_ERROR);
        }
        // 验证码正确，发送短信
        redisTemplate.delete(key);
        return this.sendCode(SendCodeEnum.USER_REGISTER, sendCodeRequest.getTo());
    }

    private JsonData sendCode(SendCodeEnum type, String to) {
        String cacheKey = String.format(RedisKeyTemplate.CHECK_CODE_KEY, type.name(), to);
        String cacheValue = redisTemplate.opsForValue().get(cacheKey);

        if (StringUtils.isNotBlank(cacheValue)) {
            long ttl = Long.parseLong(cacheValue.split(ShortLinkConstant.UNDERLINE)[1]);
            // 当前时间戳-验证码发送的时间戳，如果小于60s，则不给发送
            if (CommonUtil.getCurrentTimestamp() - ttl < CODE_EXPIRED_TIME) {
                log.warn("NotifyServiceImpl | sendCode | {} 重复发送验证码，时间间隔小于60s", to);
                return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);
            }
        }
        // 没重复生成
        String code = CommonUtil.getRandomCode(6);
        cacheValue = String.join(ShortLinkConstant.UNDERLINE, code, String.valueOf(CommonUtil.getCurrentTimestamp()));
        redisTemplate.opsForValue().set(cacheKey, cacheValue, CODE_EXPIRED_TIME, TimeUnit.MILLISECONDS);

        if (CheckUtil.isEmail(to)) {
            // TODO 发送邮箱验证码
        }
        if (CheckUtil.isPhone(to)) {
            // 发送手机验证码
            smsComponent.send(to, smsConfig.getTemplateId(), code);
        }
        return JsonData.buildSuccess();
    }
}
